package com.jyy.prefabricated.handler;


import com.jyy.prefabricated.common.AjaxResult;
import com.jyy.prefabricated.exception.CustomException;
import lombok.extern.slf4j.Slf4j;

import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

/**
 * @author: zjj
 * @desc
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 忽略参数异常处理器
     *
     * @param e 忽略参数异常 (列@RequestParam 的参数为空)
     * @return ResponseResult
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public AjaxResult parameterMissingExceptionHandler(MissingServletRequestParameterException e) {
        log.error("", e);
        return AjaxResult.error("请求参数 " + e.getParameterName() + " 不能为空");
    }

    /**
     * 缺少请求体异常处理器
     *
     * @param e 缺少请求体异常 （传的参数对象Json序列化异常）
     * @return ResponseResult
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public AjaxResult parameterBodyMissingExceptionHandler(HttpMessageNotReadableException e) {
        log.error("", e);
        return AjaxResult.error("参数结构异常");
    }

    /**
     * 参数效验异常处理器
     *
     * @param e 参数验证异常 （@Valid 参数校验异常）
     * @return AjaxResult
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public AjaxResult parameterExceptionHandler(MethodArgumentNotValidException e) {
        log.error("", e);
        // 获取异常信息
        BindingResult exceptions = e.getBindingResult();
        // 判断异常中是否有错误信息，如果存在就使用异常中的消息，否则使用默认消息
        if (exceptions.hasErrors()) {
            List<ObjectError> errors = exceptions.getAllErrors();
            if (!errors.isEmpty()) {
                // 这里列出了全部错误参数，按正常逻辑，只需要第一条错误即可
                FieldError fieldError = (FieldError) errors.get(0);
                return AjaxResult.error(fieldError.getDefaultMessage());
            }
        }
        return AjaxResult.error("参数验证异常");
    }

    /**
     * 自定义错误异常处理器
     *
     * @param e 自定义异常 （自定义错误异常）
     * @return AjaxResult
     */
    @ExceptionHandler({CustomException.class})
    public AjaxResult customExceptionHandler(CustomException e) {
        log.error("", e);
        // 判断异常中是否有错误信息，如果存在就使用异常中的消息，否则使用默认消息
        if (!StringUtils.isEmpty(e.getMessage())) {
            return AjaxResult.error(e.getMessage());
        }
        return AjaxResult.error("请求异常");
    }
}
